package com.example.admin.photovallfalldemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by Dingsheng on 2016/4/19.
 */
public class MyScrollView1 extends ScrollView implements View.OnTouchListener {

    /**
     * 每页加载图片的数量
     */
    private final static int PAGE_SIZE = 15;

    /**
     * 记录当前已加载到第几页
     */
    private int page;
    /**
     * 每一列的宽度
     */
    private int columnWidth;
    /**
     * 当前第一列的高度
     */
    private int firstColumnHeight;

    /**
     * 当前第二列的高度
     */
    private int secondColumnHeight;

    /**
     * 当前第三列的高度
     */
    private int thirdColumnHeight;

    /**
     * 是否已加载过一次layout，这里onLayout中的初始化只需加载一次
     */
    private boolean loadOnce;
    /**
     * 对图片进行管理的工具类
     */
    private ImageLoader imageLoader;
    /**
     * 第一列的布局
     */
    private LinearLayout firstColumn;

    /**
     * 第二列的布局
     */
    private LinearLayout secondColumn;

    /**
     * 第三列的布局
     */
    private LinearLayout thirdColumn;
    /**
     * 记录所有正在下载或等待下载的任务。
     */
    private static Set<LoadImageTask> taskCollection;

    /**
     * MyScrollView下的直接子布局。
     */
    private static View scrollLayout;

    /**
     * MyScrollView布局的高度。
     */
    private static int scrollViewHeight;

    /**
     * 记录上垂直方向的滚动距离。
     */
    private static int lastScrollY = -1;

    /**
     * 记录所有界面上的图片，用以可以随时控制对图片的释放。
     */
    private List<ImageView> imageViewList = new ArrayList<ImageView>();
    /**
     * 在Handler中进行图片可见性检查的判断，以及加载更多图片的操作。
     */

    private final static Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            MyScrollView1 myScrollView = (MyScrollView1) msg.obj;
            int scrollY = myScrollView.getScrollY();
            //如果当前位置和上次位置相同，则表示滚动停止
            if (scrollY==lastScrollY){
                // 当滚动的最底部，并且当前没有正在下载的任务时，开始加载下一页的图片
                if (scrollViewHeight + scrollY >= scrollLayout.getHeight()
                        && taskCollection.isEmpty()) {
                    myScrollView.loadMoreImages();
                }
                myScrollView.checkVisibolily();
            }






        }
    };

    public MyScrollView1(Context context, AttributeSet attrs) {
        super(context, attrs);
        imageLoader = ImageLoader.getInstance();
        taskCollection = new HashSet<LoadImageTask>();
        setOnTouchListener(this);

    }


    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        if (changed && !loadOnce) {
            scrollViewHeight = getHeight();
            scrollLayout = getChildAt(0);
            firstColumn = (LinearLayout) findViewById(R.id.first_column);
            secondColumn = (LinearLayout) findViewById(R.id.second_column);
            thirdColumn = (LinearLayout) findViewById(R.id.third_column);
            loadMoreImages();
        }

    }


    /**
     * 开始加载下一页的图片，每张图片都会开启一个异步线程去下载。
     */

    public void loadMoreImages() {
        int startIndex = page * PAGE_SIZE;
        int endIndex = page * PAGE_SIZE + PAGE_SIZE;
        if (startIndex < Images.imageUrls.length) {
            Toast.makeText(getContext(), "正在加载...", Toast.LENGTH_SHORT).show();

            if (endIndex > Images.imageUrls.length) {
                endIndex = Images.imageUrls.length;
            }
            for (int i = startIndex; i < endIndex; i++) {
                LoadImageTask task = new LoadImageTask();
                taskCollection.add(task);
                task.execute(Images.imageUrls[i]);
            }
            page++;
        } else {
            Toast.makeText(getContext(), "已没有更多图片", Toast.LENGTH_SHORT).show();
        }


    }

    /**
     * 遍历imageViewList中的每张图片，对图片的可见性进行检查，如果图片已经离开屏幕可见范围，则将图片替换成一张空图。
     */


    public void checkVisibolily() {
        for (int i = 0; i < imageViewList.size(); i++) {












        }


    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.ACTION_UP == event.getAction()) {
            Message message=new Message();
            message.obj=this;
            handler.sendMessageDelayed(message,5*1000);
        }
        return false;
    }


    class LoadImageTask extends AsyncTask<String, Void, Bitmap> {
        /**
         * 图片的url地址
         *
         * @param context
         */
        private String imageUrl;
        /**
         * 可重复使用的ImageView
         */
        private ImageView mImageView;


        public LoadImageTask(Context context) {
            super();
        }

        public LoadImageTask() {
            super();
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            imageUrl = params[0];
            Bitmap imageBitmap = imageLoader.getBitmapFromMemoryCache(imageUrl);
            if (imageBitmap == null) {
                imageBitmap = loadImage(imageUrl);
            }
            return imageBitmap;
        }

        /**
         * 根据传入的URL，对图片进行加载。如果这张图片已经存在于SD卡中，则直接从SD卡里读取，否则就从网络上下载。
         * <p/>
         * imageUrl
         * 图片的URL地址
         *
         * @return 加载到内存的图片。
         */
        public Bitmap loadImage(String imageUrl) {
            File imageFile = new File(imageUrl);
            if (imageFile.exists()) {
                downLoadImage(imageUrl);
            }
            Bitmap bitmap = ImageLoader.decodeSampledBitmapFromResource(imageUrl, columnWidth);
            imageLoader.addBitmapToMemoryCache(imageUrl, bitmap);
            return bitmap;
        }

        /**
         * 将图片下载到SD卡缓存起来。
         * <p/>
         * imageUrl
         * 图片的URL地址。
         */
        public void downLoadImage(String imageUrl) {
            HttpURLConnection urlConnection = null;
            BufferedOutputStream bos = null;
            BufferedInputStream bis = null;
            File imageFile = new File(imageUrl);
            try {
                URL url = new URL(imageUrl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setConnectTimeout(5 * 1000);
                urlConnection.setReadTimeout(15 * 1000);
                urlConnection.setDoInput(true);
                urlConnection.setDoOutput(true);
                bis = new BufferedInputStream(urlConnection.getInputStream());
                File file = new File(imageUrl);
                bos = new BufferedOutputStream(new FileOutputStream(file));
                int len = -1;
                byte[] b = new byte[1024];
                while ((len = bis.read()) != -1) {
                    bos.write(b, 0, b.length);
                    bos.flush();
                }
                if (imageFile != null) {
                    Bitmap bitmap = ImageLoader.decodeSampledBitmapFromResource(imageFile.getPath(), columnWidth);
                    imageLoader.addBitmapToMemoryCache(imageUrl, bitmap);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bos != null) {
                    try {
                        bos.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        }


        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if (bitmap != null) {
                double ratio = bitmap.getWidth() / (columnWidth * 1.0);
                int scaledHeight = (int) (bitmap.getHeight() / ratio);
                addImageView(bitmap, columnWidth, scaledHeight);
            }
            taskCollection.remove(this);
        }

        /**
         * 向ImageView中添加一张图片
         *
         * @param bitmap      待添加的图片
         * @param imageWidth  图片的宽度
         * @param imageHeight 图片的高度
         */
        public void addImageView(Bitmap bitmap, int imageWidth, int imageHeight) {

            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    imageWidth, imageHeight);
            if (mImageView != null) {
                mImageView.setImageBitmap(bitmap);
            } else {
                ImageView imageView = new ImageView(getContext());
                imageView.setLayoutParams(params);
                imageView.setImageBitmap(bitmap);
                imageView.setScaleType(ImageView.ScaleType.FIT_XY);
                imageView.setPadding(5, 5, 5, 5);
                imageView.setTag(R.string.image_url, imageUrl);
                findColumnToAdd(imageView, imageHeight).addView(imageView);
                imageViewList.add(imageView);
            }


        }

        /**
         * 找到此时应该添加图片的一列。原则就是对三列的高度进行判断，当前高度最小的一列就是应该添加的一列。
         *
         * @return 应该添加图片的一列
         * @para imageView
         * @para imageHeight
         */

        private LinearLayout findColumnToAdd(ImageView imageView,
                                             int imageHeight) {
            if (firstColumnHeight <= secondColumnHeight) {
                if (firstColumnHeight <= thirdColumnHeight) {
                    imageView.setTag(R.string.border_top, firstColumnHeight);
                    firstColumnHeight += imageHeight;
                    imageView.setTag(R.string.border_bottom, firstColumnHeight);
                    return firstColumn;
                }
                imageView.setTag(R.string.border_top, thirdColumnHeight);
                thirdColumnHeight += imageHeight;
                imageView.setTag(R.string.border_bottom, thirdColumnHeight);
                return thirdColumn;
            } else {
                if (secondColumnHeight <= thirdColumnHeight) {
                    imageView.setTag(R.string.border_top, secondColumnHeight);
                    secondColumnHeight += imageHeight;
                    imageView
                            .setTag(R.string.border_bottom, secondColumnHeight);
                    return secondColumn;
                }
                imageView.setTag(R.string.border_top, thirdColumnHeight);
                thirdColumnHeight += imageHeight;
                imageView.setTag(R.string.border_bottom, thirdColumnHeight);
                return thirdColumn;
            }
        }


    }


}
